home *** CD-ROM | disk | FTP | other *** search
- ---------------------------------------------------------------------------
-
- Appendix P
- typedef Frog* T;
-
- // Boolean type
- typedef int Truth;
-
- // A node contains a value of type T. Each node can link
- // itself to another node
-
- class Node {
- public:
- Node( T x) { val = x; Next = 0; }
- Node *next() { return Next; }
- void link( Node *neighbor) { Next = neighbor; }
- T value() { return val; }
- private:
- Node *Next;
- T val;
- };
-
- // A word about preconditions: if the precondition is
- // not satisfied, the operation should not be performed.
- // If, nonetheless, the operation is performed, the results are
- // indeterminate ( e.g. spurious results, corruption of program,
- // memory fault ... )
-
- // Lisp of T is a Lisp-style list of T values.
- // It is a simple abstraction, useful in its own right,
- // also useful for building more sophisticated list abstractions.
- // Note: Lists with reference semantics are obtained by
- // substituting T* for T.
-
- class Lisp {
- public:
- Lisp() { head = 0; }
-
- Truth isempty() { return head == 0; }
-
- // lget returns the value at the head of the lisp
- // without deleting it. This is car in LISP.
- // precondition: !isempty() (lisp is not empty)
- T lget() { return head->value(); }
-
- // ltail returns the tail of the lisp. cdr in LISP.
- Lisp ltail()
- {
- Lisp r;
- if( !isempty() )
- r.head = head->next();
- return r;
- }
-
- // ladd inserts a new element with value x at the head
- // of the lisp
- void ladd(T x)
- {
- Node *p = new Node(x); // error return of new should
- // be checked ...
- if( !isempty() ) // member fun. calls member fun.
- p->link( head);
- head = p;
- }
-
- // ldel deletes value at the head of the list
- // and returns the value
- // precondition: !isempty() (lisp is not empty)
- T ldel()
- {
- Node *t = head;
- T r = head->value();
- head = head->next();
- delete t;
- return r;
- }
-
- // some functions useful for building parametric List[T] with
- // random access to element on its index in the list
-
- // after inserts the value x after the first element in the
- // lisp. If the lisp is empty, x becomes first element
- void after( T x)
- {
- Node *p = new Node(x); // error return of new should
- // be checked ...
- if( isempty() )
- head = p;
- else {
- p->link( head->next() );
- head->link( p);
- }
- }
-
- // pluck deletes the 2nd element in the lisp
- // precondition: lisp has at least 2 elements
- // i.e. !tail().isempty()
- T pluck()
- {
- Node *t = head->next();
- T r = t->value();
- head->link( t->next());
- delete t;
- return r;
- }
-
- private:
- Node *head;
- };
-
- // Pond is a kind of Lisp wherein the individual elements can
- // be randomly accessed. Element indices start at 0.
- // Note: Pond inherits all of the properties of Lisp
-
- class Pond : public Lisp {
- public:
- Pond();
-
- Pond( Lisp &l);
-
- // length returns the number of elements in the list
- int length();
-
- // get returns the nth value in the list
- // precondition: !isempty() && 0 <= n < length()
- T get( int n);
-
- // del deletes the nth value in the list and returns it.
- // precondition: !isempty() && 0 <= n < length()
- T del( int n);
-
- // add adds x after element n
- // precondition: n >= 0
- // Note: if you want to insert to the head of the Pond,
- // use the inherited void ladd( T x) member function
- void add( T x, int n);
-
- // tail returns the tail of the Pond.
- Pond tail();
-
- // tail( n) returns the n-th tail of the Pond
- Pond tail( int n);
- };
-
- int Pond::length()
- {
- int n;
- Pond r;
-
- for( n = 0, r = *this; !r.isempty(); n++, r = r.tail() )
- ;
- return n;
- }
-
- T Pond::get( int n) { return tail( n).lget(); }
-
- T Pond::del( int n)
- {
- return n ? tail( n - 1).pluck() : ldel();
- }
-
- void Pond::add( T x, int n) { tail( n).after( x); }
-
- Pond::Pond() : () {}
-
- Pond::Pond( Lisp &l) { (*(Lisp *)this) = l; }
-
- Pond Pond::tail() { return Pond( ltail()); }
-
- Pond Pond::tail( int n)
- {
- for( Pond r = *this; !r.isempty() && (n-- > 0); r = r.tail() )
- ;
- return r;
- }
-
- ---------------------------------------------------------------------------
-